// Package log 实现了 bakctl 的 log 子命令功能。
//
// 该包提供了查看和分析备份日志的功能，支持：
//   - 显示备份任务的执行历史记录
//   - 提供详细的备份状态和错误信息
//   - 支持多种日志查看和过滤选项
//   - 提供日志统计和分析功能
//
// 主要功能包括：
//   - 从数据库查询备份记录
//   - 格式化日志信息为可读的表格
//   - 提供时间范围和状态过滤
//   - 显示备份文件大小、耗时等统计信息
//   - 支持导出日志到文件
//
// 日志信息包括执行时间、状态、文件大小、错误信息等详细数据。
package log

import (
	"fmt"
	"os"
	"path/filepath"

	DB "gitee.com/MM-Q/bakctl/internal/db"
	"gitee.com/MM-Q/bakctl/internal/types"
	"gitee.com/MM-Q/bakctl/internal/utils"
	"gitee.com/MM-Q/colorlib"
	"github.com/jedib0t/go-pretty/v6/table"
	"github.com/jedib0t/go-pretty/v6/text"
	"github.com/jmoiron/sqlx"
)

// emptyToPlaceholder 如果字符串为空则返回占位符，否则返回原字符串
//
// 参数:
//   - s: 输入字符串
//
// 返回值:
//   - string: 返回处理后的字符串
//
// 说明:
//   - 当输入字符串为空时，返回占位符 "---"；否则返回原字符串。
func emptyToPlaceholder(s string) string {
	if s == "" {
		return "---"
	}
	return s
}

// LogCmdMain 日志命令主函数
//
// 参数:
//   - db: 数据库连接
//   - cl: 颜色库
//
// 返回值:
//   - error: 错误信息
func LogCmdMain(db *sqlx.DB, cl *colorlib.ColorLib) error {
	// 参数验证
	if err := validateLogFlags(); err != nil {
		return err
	}

	// 创建表格
	t := table.NewWriter()

	// 设置表格样式
	if style, ok := types.TableStyle[logCmdTableStyle.Get()]; ok {
		t.SetStyle(style)
	} else {
		return fmt.Errorf("表格样式不存在: %s, 可选样式: %v", logCmdTableStyle.Get(), types.TableStyleList)
	}

	// 查询备份记录列表
	data, err := getBackupRecords(db)
	if err != nil {
		return fmt.Errorf("查询备份记录失败: %w", err)
	}

	// 提前检查是否有备份记录
	if len(data) == 0 {
		cl.Yellow("当前没有备份记录")
		cl.Whitef("提示: 使用 '%s run' 命令执行备份任务来生成记录", filepath.Base(os.Args[0]))
		return nil
	}

	// 使用标准输出作为输出目标
	t.SetOutputMirror(os.Stdout)

	// 根据简洁模式设置不同的表头和列配置
	if logCmdSimple.Get() {
		// 简洁模式：只显示任务ID、任务名、版本ID、状态、失败信息
		t.AppendHeader(table.Row{"任务ID", "任务名", "版本ID", "状态", "失败信息"})

		t.SetColumnConfigs([]table.ColumnConfig{
			{Name: "任务ID", Align: text.AlignCenter, WidthMaxEnforcer: text.WrapHard},
			{Name: "任务名", Align: text.AlignLeft, WidthMaxEnforcer: text.WrapHard},
			{Name: "版本ID", Align: text.AlignLeft, WidthMaxEnforcer: text.WrapHard},
			{Name: "状态", Align: text.AlignCenter, WidthMaxEnforcer: text.WrapHard},
			{Name: "失败信息", Align: text.AlignCenter, WidthMaxEnforcer: text.WrapHard},
		})

		// 添加简洁模式数据行
		for _, record := range data {
			t.AppendRow(table.Row{
				record.TaskID,    // 任务ID
				record.TaskName,  // 任务名
				record.VersionID, // 版本ID
				record.Status,    // 状态
				emptyToPlaceholder(record.FailureMessage), // 失败信息
			})
		}
	} else {
		// 完整模式：显示所有信息
		t.AppendHeader(table.Row{"任务ID", "任务名", "版本ID", "备份文件名", "文件大小", "存储路径", "状态", "失败信息", "校验码", "创建时间"})

		t.SetColumnConfigs([]table.ColumnConfig{
			{Name: "任务ID", Align: text.AlignCenter, WidthMaxEnforcer: text.WrapHard},
			{Name: "任务名", Align: text.AlignLeft, WidthMaxEnforcer: text.WrapHard},
			{Name: "版本ID", Align: text.AlignLeft, WidthMaxEnforcer: text.WrapHard},
			{Name: "备份文件名", Align: text.AlignLeft, WidthMaxEnforcer: text.WrapHard},
			{Name: "文件大小", Align: text.AlignRight, WidthMaxEnforcer: text.WrapHard},
			{Name: "存储路径", Align: text.AlignLeft, WidthMaxEnforcer: text.WrapHard},
			{Name: "状态", Align: text.AlignCenter, WidthMaxEnforcer: text.WrapHard},
			{Name: "失败信息", Align: text.AlignCenter, WidthMaxEnforcer: text.WrapHard},
			{Name: "校验码", Align: text.AlignLeft, WidthMaxEnforcer: text.WrapHard},
			{Name: "创建时间", Align: text.AlignCenter, WidthMaxEnforcer: text.WrapHard},
		})

		// 添加完整模式数据行
		for _, record := range data {
			t.AppendRow(table.Row{
				record.TaskID,    // 任务ID
				record.TaskName,  // 任务名
				record.VersionID, // 版本ID
				emptyToPlaceholder(record.BackupFilename), // 备份文件名
				utils.FormatBytes(record.BackupSize),      // 文件大小
				record.StoragePath,                        // 存储路径
				record.Status,                             // 状态
				emptyToPlaceholder(record.FailureMessage), // 失败信息
				emptyToPlaceholder(record.Checksum),       // 校验码
				utils.ConvertUTCToLocal(record.CreatedAt), // 创建时间（转换为本地时间）
			})
		}
	}

	// 渲染表格
	t.Render()

	return nil
}

// validateLogFlags 验证log命令的标志参数
func validateLogFlags() error {
	// 验证任务选择
	hasID := logCmdTaskID.Get() > 0       // 任务ID必须大于0
	hasName := logCmdTaskName.Get() != "" // 任务名称不能为空

	if hasID && hasName {
		return fmt.Errorf("--id 和 --name/-n 不能同时使用")
	}

	// 验证limit参数
	if logCmdLimit.Get() < 0 {
		return fmt.Errorf("--limit/-l 必须大于等于0")
	}

	return nil
}

// getBackupRecords 根据标志参数获取备份记录
func getBackupRecords(db *sqlx.DB) ([]types.BackupRecord, error) {
	taskID := logCmdTaskID.Get()     // 任务ID
	taskName := logCmdTaskName.Get() // 任务名称
	limit := logCmdLimit.Get()       // 限制条数
	onlyFailed := logCmdFailed.Get() // 只显示失败记录

	// 使用新的统一查询方法
	return DB.GetBackupRecordsWithFilter(db, taskID, taskName, onlyFailed, limit)
}
